﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows.Forms;

namespace QD.Tools
{
    public static class DataGridViewHelper
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="grid"></param>
        public static void InitGrid(this DataGridView grid)
        {
            InitGrid(grid, true, true);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="grid"></param>
        /// <param name="isRegisterDoubleClick">是否注册单元格双击事件</param>
        /// <param name="isRegEditingControlShowing">是否注册编辑单元格的控件事件</param>
        /// <param name="addcontextMenuStrip">是否添加右键快捷菜单</param>
        public static void InitGrid(this DataGridView grid, bool isRegCellDoubleClick, bool isRegEditingControlShowing, bool addcontextMenuStrip)
        {
            InitGrid(grid, isRegCellDoubleClick, isRegEditingControlShowing);
            if (addcontextMenuStrip)
            {
                ContextMenuStrip strip = new ContextMenuStrip();
                grid.RowTemplate.ContextMenuStrip = strip;

                ToolStripMenuItem item1 = new ToolStripMenuItem("复制单元格");
                item1.Click += item1_Click;
                ToolStripMenuItem item2 = new ToolStripMenuItem("复制所有选中单元格");
                item2.Click += item2_Click;
                strip.Items.Add(item1);
                strip.Items.Add(item2);
            }
        }

        static void item1_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem item = (ToolStripMenuItem)sender;
            ContextMenuStrip strip = (ContextMenuStrip)item.Owner;

            DataGridView grid = (DataGridView)strip.SourceControl;
            grid.CopyFirstSelectedCellValue();
        }

        static void item2_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem item = (ToolStripMenuItem)sender;
            ContextMenuStrip strip = (ContextMenuStrip)item.Owner;

            DataGridView grid = (DataGridView)strip.SourceControl;
            grid.CopySelectedCellsValue();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="grid"></param>
        /// <param name="isRegisterDoubleClick">是否注册单元格双击事件</param>
        /// <param name="isRegisterDoubleClick">是否注册编辑单元格的控件事件</param>
        public static void InitGrid(this DataGridView grid, bool isRegCellDoubleClick, bool isRegEditingControlShowing)
        {
            InitGrid(grid, isRegCellDoubleClick);
            if (isRegEditingControlShowing)
            {
                grid.EditingControlShowing += grid_proEdit_EditingControlShowing;
            }
        }

        static void grid_proEdit_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
        {
            DataGridView grid = (DataGridView)sender;
            int x = grid.CurrentCell.RowIndex;
            int y = grid.CurrentCell.ColumnIndex;

            if (grid.Rows[x].Cells[y] is DataGridViewComboBoxCell && grid.Rows[x].Cells[y].IsInEditMode)
            {
                ComboBox cbo = e.Control as ComboBox;
                if (cbo != null)
                {
                    cbo.DropDownStyle = ComboBoxStyle.DropDown;
                    cbo.AutoCompleteSource = AutoCompleteSource.ListItems;
                    cbo.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="grid"></param>
        /// <param name="isRegCellDoubleClick">是否注册单元格双击事件</param>
        public static void InitGrid(this DataGridView grid, bool isRegCellDoubleClick)
        {
            grid.AutoGenerateColumns = false;
            grid.RowTemplate.Height = 20;
            grid.EditMode = DataGridViewEditMode.EditOnEnter;
            grid.AllowUserToDeleteRows = false;
            grid.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
            grid.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
            grid.ColumnHeadersHeight = 22;
            grid.AllowUserToOrderColumns = true;

            //grid.EnableHeadersVisualStyles = false;
            //grid.ColumnHeadersDefaultCellStyle.BackColor = Color.Blue;

            grid.RowPostPaint += grid_RowPostPaint;
            grid.DataError += grid_DataError;
            if (isRegCellDoubleClick)
            {
                grid.CellDoubleClick += DataGridView_CellDoubleClick;
            }

            for (int i = 0; i < grid.Columns.Count; i++)
            {
                if (grid.Columns[i].HeaderText == "创建日期" ||
                    grid.Columns[i].HeaderText == "创建时间")
                {
                    grid.Columns[i].Width = 120;
                }
                else if (grid.Columns[i] is DataGridViewCheckBoxColumn)
                {
                    int len = grid.Columns[i].HeaderText.Length;
                    grid.Columns[i].Width = 50 + (len * 6);
                }
            }
        }

        static void grid_DataError(object sender, DataGridViewDataErrorEventArgs e)
        {
            if (e.Context == (DataGridViewDataErrorContexts.Parsing | DataGridViewDataErrorContexts.Commit))
            {
                e.Cancel = true;
                Tools.PromptHelper.Prompt("输入内容不正确，请检查输入的值是否为正确的数据类型！");
            }
            //如果不注释，当为ComBobox下拉列时，如果当前值在下拉列中不存在，会一直提示以下错误
            //else if (e.Context == (DataGridViewDataErrorContexts.Formatting | DataGridViewDataErrorContexts.Display))
            //{
            //    e.Cancel = true;
            //    Tools.PromptHelper.Prompt("显示数据时错误，请检查单元格的值是否为正确的数据类型！");
            //}
        }

        public static void DataGridView_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex > -1 && e.ColumnIndex > -1)
            {
                DataGridView grid = (DataGridView)sender;
                if (grid.Rows[e.RowIndex].Cells[e.ColumnIndex] is DataGridViewTextBoxCell && grid.Rows[e.RowIndex].Cells[e.ColumnIndex].IsInEditMode)
                {
                    object value = grid.Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
                    Location location = new Location(e.RowIndex, e.ColumnIndex);
                    location.Obj = grid;
                    OpenWindowSimpleFrm frm = new OpenWindowSimpleFrm(value == DBNull.Value ? string.Empty : value.ToString(), location);
                    frm.SureEvent += frm_SureEvent;
                    frm.ShowDialog();
                }
            }
        }

        static void frm_SureEvent(object sourceData, object targetData)
        {
            Location location = sourceData as Location;
            DataGridView grid = (DataGridView)location.Obj;
            grid.Rows[location.X].Cells[location.Y].Value = targetData.ToString();
        }

        /// <summary>
        /// 增加行号
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        static void grid_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
        {
            try
            {
                DataGridView grid = sender as DataGridView;
                Rectangle rectangle = new Rectangle(e.RowBounds.Location.X,
                        e.RowBounds.Location.Y,
                        grid.RowHeadersWidth - 8,
                        e.RowBounds.Height);

                TextRenderer.DrawText(e.Graphics, (e.RowIndex + 1).ToString(),
                    grid.RowHeadersDefaultCellStyle.Font,
                    rectangle,
                    grid.RowHeadersDefaultCellStyle.ForeColor,
                    TextFormatFlags.VerticalCenter | TextFormatFlags.Right);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 结束编辑状态（修复了最后一个单元格未提交到保存的问题）
        /// </summary>
        public static void EndEditState(this DataGridView grid)
        {
            grid.EndEdit();
            grid.CurrentCell = null; ;//该行的作用是取消datagridview行的编辑状态
        }

        /// <summary>
        /// 复制第一个选中单元格的值
        /// </summary>
        /// <param name="grid"></param>
        public static void CopyFirstSelectedCellValue(this DataGridView grid)
        {
            DataGridViewSelectedCellCollection cells = grid.SelectedCells;
            if (cells.Count > 0)
            {
                DataGridViewCell cell = cells[0];
                Clipboard.Clear();
                Clipboard.SetText(cell.Value.ToString().Length > 0 ? cell.Value.ToString() : " ");
            }
        }

        /// <summary>
        /// 复制所有选中单元格的值
        /// </summary>
        /// <param name="grid"></param>
        public static void CopySelectedCellsValue(this DataGridView grid)
        {
            StringBuilder str = new StringBuilder();
            DataGridViewSelectedCellCollection cells = grid.SelectedCells;
            if (cells.Count > 0)
            {
                int minRowIndex = cells[0].RowIndex;
                int maxRowIndex = cells[0].RowIndex;

                int minColIndex = cells[0].ColumnIndex;
                int maxColIndex = cells[0].ColumnIndex;

                foreach (DataGridViewCell cell in cells)
                {
                    if (cell.RowIndex < minRowIndex)
                    {
                        minRowIndex = cell.RowIndex;
                    }
                    if (cell.RowIndex > maxRowIndex)
                    {
                        maxRowIndex = cell.RowIndex;
                    }
                    if (cell.ColumnIndex < minColIndex)
                    {
                        minColIndex = cell.ColumnIndex;
                    }
                    if (cell.ColumnIndex > maxColIndex)
                    {
                        maxColIndex = cell.ColumnIndex;
                    }
                }

                int lastRowCount = minRowIndex;
                for (int i = minRowIndex; i <= maxRowIndex; i++)
                {
                    if (lastRowCount != i)
                    {
                        str.Append(GeneralTools.EnterStrings);
                        lastRowCount = i;
                    }
                    for (int j = minColIndex; j <= maxColIndex; j++)
                    {
                        if (grid.Rows[i].Cells[j].Selected)
                        {
                            if (j != minColIndex)
                            {
                                str.Append("  ");
                            }
                            str.Append(grid.Rows[i].Cells[j].Value);
                        }
                    }
                }

                Clipboard.Clear();
                Clipboard.SetText(str.ToString());
            }
        }

        /// <summary>
        /// 删除选择的行
        /// </summary>
        /// <param name="grid"></param>
        public static void DeleteSelectedRows(this DataGridView grid)
        {
            IList<int> rowsIndexList = grid.GetSelectRowsIndex();

            for (int i = rowsIndexList.Count - 1; i >= 0; i--)
            {
                if (!grid.Rows[rowsIndexList[i]].IsNewRow)
                {
                    grid.Rows.RemoveAt(rowsIndexList[i]);
                }
            }
        }

        /// <summary>
        /// 删除所有行
        /// </summary>
        /// <param name="grid"></param>
        public static void DeleteAllRows(this DataGridView grid)
        {
            if (grid.DataSource != null)
            {
                int length = grid.Rows.Count;
                for (int i = length - 1; i >= 0; i--)
                {
                    if (!grid.Rows[i].IsNewRow)
                    {
                        grid.Rows.RemoveAt(i);
                    }
                }
            }
        }

        /// <summary>
        /// 取所有行
        /// </summary>
        /// <param name="grid"></param>
        public static IList<DataGridViewRow> GetAllRows(this DataGridView grid)
        {
            IList<DataGridViewRow> rowsList = new List<DataGridViewRow>();
            DataGridViewRowCollection rows = grid.Rows;
            foreach (DataGridViewRow row in rows)
            {
                if (!row.IsNewRow)
                {
                    rowsList.Add(row);
                }
            }

            return rowsList;
        }

        /// <summary>
        /// 取选中行
        /// </summary>
        /// <param name="grid"></param>
        public static IList<DataGridViewRow> GetSelectRows(this DataGridView grid)
        {
            IList<int> rowsIndexList = new List<int>();
            IList<DataGridViewRow> rowsList = new List<DataGridViewRow>();

            DataGridViewSelectedCellCollection rows = grid.SelectedCells;

            foreach (DataGridViewCell cell in rows)
            {
                if (!rowsIndexList.Any(p => p == cell.RowIndex))
                {
                    rowsIndexList.Add(cell.RowIndex);
                    rowsList.Add(grid.Rows[cell.RowIndex]);
                }
            }

            return rowsList;
        }

        /// <summary>
        /// 取选中行的行索引
        /// </summary>
        /// <param name="grid"></param>
        public static IList<int> GetSelectRowsIndex(this DataGridView grid)
        {
            IList<int> rowsIndexList = new List<int>();
            DataGridViewSelectedCellCollection rows = grid.SelectedCells; ;

            foreach (DataGridViewCell cell in rows)
            {
                if (!rowsIndexList.Any(p => p == cell.RowIndex))
                {
                    rowsIndexList.Add(cell.RowIndex);
                }
            }
            rowsIndexList = (from s in rowsIndexList
                             orderby s ascending
                             select s).ToList();

            return rowsIndexList;
        }

        /// <summary>
        ///  取某单元格值
        /// </summary>
        public static string GetCellValueToString(this DataGridViewRow row, string colName)
        {
            object value = row.Cells[colName].Value;
            return value == null || value == DBNull.Value ? string.Empty : value.ToString();
        }

        /// <summary>
        ///  取某单元格值
        /// </summary>
        public static bool GetCellValueToBool(this DataGridViewRow row, string colName)
        {
            object value = row.Cells[colName].Value;
            return value == null || value == DBNull.Value ? false : Convert.ToBoolean(value);
        }

        /// <summary>
        ///  取某单元格值
        /// </summary>
        public static DateTime GetCellValueToDateTime(this DataGridViewRow row, string colName)
        {
            object value = row.Cells[colName].Value;
            return value == null || value == DBNull.Value ? DateTime.Now : Convert.ToDateTime(value);
        }

        /// <summary>
        ///  取某单元格值
        /// </summary>
        public static DateTime? GetCellValueToNullDateTime(this DataGridViewRow row, string colName)
        {
            object value = row.Cells[colName].Value;
            if (value == null || value == DBNull.Value)
            {
                return null;
            }
            else
            {
                return Convert.ToDateTime(value);
            }
        }

        /// <summary>
        ///  取某单元格值
        /// </summary>
        public static int GetCellValueToInt(this DataGridViewRow row, string colName)
        {
            object value = row.Cells[colName].Value;

            return value == null || value == DBNull.Value ? 0 : Convert.ToInt32(value);
        }

        /// <summary>
        ///  取某单元格值
        /// </summary>
        public static int? GetCellValueToNullInt(this DataGridViewRow row, string colName)
        {
            object value = row.Cells[colName].Value;
            if (value == null || value == DBNull.Value)
            {
                return null;
            }
            else
            {
                return Convert.ToInt32(value);
            }
        }

        /// <summary>
        ///  取某单元格值
        /// </summary>
        public static decimal GetCellValueToDecimal(this DataGridViewRow row, string colName)
        {
            object value = row.Cells[colName].Value;

            return value == null || value == DBNull.Value ? 0 : Convert.ToDecimal(value);
        }

        /// <summary>
        /// 根据DataGridViewRow的值初始化对象
        /// </summary>
        /// <param name="row"></param>
        /// <param name="obj"></param>
        public static void InitObj(this DataGridViewRow row, object obj, params string[] ignoreProperty)
        {
            PropertyInfo[] infos = obj.GetType().GetProperties();
            foreach (PropertyInfo info in infos)
            {
                if (!ignoreProperty.Contains(info.Name))
                {
                    if ((info.PropertyType.IsValueType || info.PropertyType == typeof(string))
                        && row.DataGridView.Columns.Contains(info.Name))
                    {
                        object value = row.Cells[info.Name].Value;
                        info.SetValue(obj, value.ChanageType(info.PropertyType));
                    }
                }
            }
        }

        /// <summary>
        /// 取选中第一列的DataPropertyName
        /// </summary>
        /// <param name="grid"></param>
        /// <returns></returns>
        public static string GetColumnDataPropertyName(this DataGridView grid)
        {
            DataGridViewSelectedCellCollection cells = grid.SelectedCells;
            if (cells.Count == 0)
            {
                return string.Empty;
            }
            else
            {
                return grid.Columns[cells[0].ColumnIndex].DataPropertyName;
            }
        }

        /// <summary>
        /// 初始化行
        /// </summary>
        /// <param name="grid"></param>
        /// <param name="ignoreProperty">忽略的列</param>
        public static void InitRowValue(this DataGridViewRow row, object obj, params string[] ignoreProperty)
        {
            PropertyInfo[] infos = obj.GetType().GetProperties();
            foreach (PropertyInfo info in infos)
            {
                if (!ignoreProperty.Contains(info.Name))
                {
                    if ((info.PropertyType.IsValueType || info.PropertyType == typeof(string))
                        && row.DataGridView.Columns.Contains(info.Name))
                    {
                        object value = info.GetValue(obj);
                        row.Cells[info.Name].Value = value;
                    }
                }
            }
        }

        /// <summary>
        /// 初始化行
        /// </summary>
        /// <param name="grid"></param>
        /// <param name="ignoreProperty">忽略的列</param>
        public static void InitRowValue1(this DataGridViewRow row, object obj, params string[] ignoreProperty)
        {
            PropertyInfo[] infos = obj.GetType().GetProperties();
            foreach (PropertyInfo info in infos)
            {
                if (!ignoreProperty.Contains(info.Name))
                {
                    if ((info.PropertyType.IsValueType || info.PropertyType == typeof(string))
                        && row.DataGridView.Columns.Contains(info.Name))
                    {
                        object value = info.GetValue(obj);
                        if (value != null && value.ToString().Length > 0)
                        {
                            row.Cells[info.Name].Value = value;
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 设置col的提示信息
        /// </summary>
        /// <param name="col"></param>
        public static void SetToolTipText(this  DataGridViewColumn col, string txt)
        {
            col.HeaderText += "?";
            col.ToolTipText = txt;
        }
    }
}
